<template>
	<view class="sh-barrage">
		<!-- 纵向 start -->
		<block v-if="type == 'portrait'">
			<swiper
				:current="current"
				class="sh-barrage-swiper"
				autoplay
				circular
				vertical
				:display-multiple-items="length"
				:interval="speed"
				easing-function="easeInCubic"
				@change="swiper_change"
			>
				<swiper-item v-for="(item, index) in items" :key="index">
					<view
						class="sh-barrage-swiper-item"
						:style="{
							backgroundColor: bgColor,
							color: foneColor
						}"
					>
						<slot :item="item"></slot>
						{{ item.text }}
					</view>
				</swiper-item>
			</swiper>
		</block>
		<!-- 纵向 end -->
		<!-- 横向 start -->
		<block v-if="type == 'horizontal'">
			<block v-for="(item, index) in items" :key="index">
				<view
					class="sh-barrage-item horizontal"
					:class="item.show ? 'move' : ''"
					:style="{
						top: `${item.top}px`,
						backgroundColor: bgColor,
						color: item.color,
						animationDuration: `${speed}ms`
					}"
				>
					<slot :item="item"></slot>
					{{ item.text }}
				</view>
			</block>
		</block>
		<!-- 横向 end -->
	</view>
</template>

<script>
// https://github.com/hellodigua/vue-danmaku
// import GLRandom from '@/common/utils/GLRandom.js';
let random;
export default {
	name: 'sh-barrage',
	props: {
		//轨道数量
		channels: {
			type: Number,
			default: 20
		},
		//一屏幕最多显示数量
		length: {
			type: Number,
			default: 10
		},
		//速度
		speed: {
			type: Number,
			default: 15000
		},
		//背景
		bgColor: {
			type: String,
			default: ''
		},
		//文字颜色
		foneColor: {
			type: String,
			default: ''
		},
		//循环
		loop: {
			type: Boolean,
			default: true
		},
		//类型 portrait=纵向 horizontal=横向
		type: {
			type: String,
			default: 'horizontal'
		}
	},
	data() {
		return {
			current: 0,
			windowWidth: 0,
			windowHeight: 0,
			setIn: null,
			items: []
		};
	},
	created() {
		uni.getSystemInfo({
			success: res => {
				this.windowWidth = res.windowWidth;
				this.windowHeight = res.windowHeight;
			}
		});
	},
	methods: {
		/**
		 * 轮播触发
		 * @param {Object} e
		 */
		swiper_change(e) {
			this.current = e.detail.current;
		},
		/** 随机数
		 * @param {Object} max 最大随机数
		 * @param {Object} min 最小随机数
		 */
		random(max, min) {
			return Math.floor(Math.random() * (max - min + 1) + min);
		},
		/**
		 * 随机色值
		 */
		randomColor() {
			let str = '#';
			for (let i = 0; i < 3; i++) {
				str += Math.floor(Math.random() * 256)
					.toString(16)
					.padStart(2, '0');
			}
			return str;
		},
		/**
		 * 处理数据
		 * @param {Object} arr
		 */
		handle_data(arr) {
			return new Promise((resolve, reject) => {
				let arrData = [];
				arr.map(item => {
					arrData.push({
						...item,
						show: false
					});
				});
				resolve(arrData);
			});
		},
		/**
		 * 随机轨道定位
		 */
		channels_random() {
			let win_height = this.windowHeight - this.windowHeight / 5 - 60;
			let _number = this.random(this.channels, 1);
			return win_height / _number;
		},
		/**
		 * 添加
		 */
		add(item) {
			if (this.type == 'portrait') {
				this.items.splice(this.current + this.length, 0, item);
				this.current++;
			} else {
				this.items.push({
					...item,
					top: this.channels_random(),
					color: this.foneColor == '' ? this.randomColor() : this.foneColor,
					show: true
				});
			}
		},
		/**
		 * 启动
		 */
		async start(data) {
			let res = await this.handle_data(data);
			this.items = res;
			let _num = 0;
			this.setIn = setInterval(() => {
				let len = this.items.length - 1;
				if (_num < len) {
					_num++;
				} else {
					_num = 0;
				}
				if (this.loop) {
					this.show(_num);
				} else {
					if (_num == len) {
						clearInterval(this.setIn);
					}
				}
			}, parseInt(this.speed / this.length));
		},
		/**
		 * 显示
		 * @param {Object} _index 显示的索引
		 */
		show(_index) {
			this.$set(this.items[_index], 'show', true);
			this.$set(this.items[_index], 'top', this.channels_random());
			if (this.foneColor == '') {
				this.$set(this.items[_index], 'color', this.randomColor());
			} else {
				this.$set(this.items[_index], 'color', this.foneColor);
			}
			this.remove_dom(_index);
		},
		/**
		 * 移除
		 */
		remove_dom(_index) {
			setTimeout(() => {
				this.$set(this.items[_index], 'show', false);
			}, this.speed);
		}
	}
};
</script>

<style>
.sh-barrage {
	height: 100vh;
	width: 100vw;
	z-index: 3;
	width: 100%;
	position: fixed;
	top: 0;
	left: 0;
	pointer-events: none;
}

.sh-barrage-swiper {
	position: absolute;
	left: 20upx;
	bottom: 240upx;
	width: 100vw;
}

.sh-barrage-item,
.sh-barrage-swiper-item {
	width: 100vw;
	display: inline-flex;
	align-items: center;
	padding: 0 10upx;
	line-height: 1;
	border-radius: 40upx;
	white-space: pre;
	white-space: nowrap;
	pointer-events: none;
}

.sh-barrage-item.horizontal {
	transform: translateX(100%);
	position: absolute;
	right: 0;
	height: 80upx;
}

.sh-barrage-item.background {
	background-color: rgba(0, 0, 0, 0.3);
}

.sh-barrage-item.move {
	z-index: 3;
	will-change: transform;
	animation-name: moveLeft;
	animation-timing-function: linear;
	animation-play-state: running;
}

.sh-barrage-item-text {
	font-size: 38upx;
	color: #fff;
	font-weight: 100;
	padding: 0 20upx;
}

@keyframes moveLeft {
	from {
		transform: translateX(100%);
	}

	to {
		transform: translateX(-200%);
	}
}

@-webkit-keyframes moveLeft {
	from {
		-webkit-transform: translateX(100%);
	}

	to {
		-webkit-transform: translateX(-200%);
	}
}
</style>
